package com.seaside.park.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.seaside.common.bean.Result;
import com.seaside.park.bean.LabelValue;
import com.seaside.park.bean.Rule;
import com.seaside.park.bean.StreamInfo;
import com.seaside.park.mapper.LabelValueMapper;
import com.seaside.park.mapper.RuleMapper;
import com.seaside.park.mapper.StreamInfoMapper;
import com.seaside.park.vo.StreamInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "语音播报管理")
@RestController
@RequestMapping("/api/stream_info")
public class StreamInfoAPI {

    @Autowired
    StreamInfoMapper streamInfoMapper;

    @Autowired
    RuleMapper ruleMapper;

    @Autowired
    LabelValueMapper labelValueMapper;

    @ApiOperation(value = "保存/修改语音播报信息", response = Result.class)
    @PostMapping("/save")
    public Result save(@RequestBody StreamInfo info) {
        if (info.getId() == 0) {
            streamInfoMapper.insert(info);
        } else {
            streamInfoMapper.updateById(info);
        }
        return Result.OK("保存成功！", null);
    }

    @ApiOperation(value = "根据ID删除语音播报信息", response = Result.class)
    @PostMapping("/delete")
    public Result delete(@RequestParam Integer id) {
        StreamInfo info = streamInfoMapper.selectById(id);
        if (info != null && info.getId() > 0) {
            streamInfoMapper.deleteById(info);
        }
        return Result.OK("删除成功！", null);
    }

    @ApiOperation(value = "查询所有视频流信息", response = Result.class)
    @GetMapping("/listAll")
    public Result listAll(@RequestParam(value = "curPage", defaultValue = "1") Integer curPage,
                          @RequestParam(value = "curSize", defaultValue = "10") Integer curSize) {

        Page<StreamInfoVo> page = new Page<>(curPage, curSize);
        List<StreamInfo> streamInfoList = streamInfoMapper.selectList(new QueryWrapper<>());
        List<StreamInfoVo> streamInfoVoList = streamInfoList.stream().map(streamInfo -> {
                    StreamInfoVo streamInfoVo = new StreamInfoVo();
                    streamInfoVo.setId(streamInfo.getId());
                    streamInfoVo.setName(streamInfo.getName());
                    streamInfoVo.setAudioIp(streamInfo.getAudioIp());
                    streamInfoVo.setUrl(streamInfo.getUrl());
                    // 根据 StreamInfo 的 id 查询对应的 Rule 列表
                    List<Rule> ruleList = ruleMapper.selectList(new QueryWrapper<Rule>().lambda().eq(Rule::getStreamInfoId, streamInfo.getId()));
                    List<StreamInfoVo.Rule> ruleVoList = ruleList.stream().map(rule -> {
                        StreamInfoVo.Rule ruleVo = new StreamInfoVo.Rule();
                        String areaString = rule.getArea();
                        List<String> areas = Arrays.stream(areaString.split("\\|"))
                                .collect(Collectors.toList());
                        ruleVo.setAreas(areas);
                        ruleVo.setType(rule.getType());
                        ruleVo.setId(rule.getId());
                        ruleVo.setAreaName(rule.getAreaName());
                        // 关联label-value
                        LabelValue labelValue = labelValueMapper.selectOne(new QueryWrapper<LabelValue>().eq("value", rule.getType()));
                        if (labelValue != null) {
                            ruleVo.setLabel(labelValue.getLabel());
                            ruleVo.setColor(labelValue.getColor());
                        }
                        return ruleVo;
                    }).collect(Collectors.toList());
                    // 设置规则列表-
                    streamInfoVo.setRules(ruleVoList);
                    return streamInfoVo;
                }).sorted(Comparator.comparingInt(StreamInfoVo::getId).reversed())
                .collect(Collectors.toList());

        page.setRecords(streamInfoVoList);
        return Result.OK("查询成功", page);
    }

    @ApiOperation(value = "播报信息下发", response = Result.class)
    @PostMapping("/publish")
    public Result publish(@RequestParam Integer id) {
        List<Rule> areas = ruleMapper.selectList(new QueryWrapper<Rule>().eq("stream_info_id", id));
        StreamInfo info = streamInfoMapper.selectById(id);
        // 将数据封装成 JSON
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonString = objectMapper.writeValueAsString(createVoiceJson(info, areas));
            // 创建RestTemplate实例
            RestTemplate restTemplate = new RestTemplate();
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json");
            HttpEntity<String> requestEntity = new HttpEntity<>(jsonString, headers);
            String url = "http://192.168.1.6/json";
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
            return Result.OK(jsonString);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.Error("Error HTTP Request！");
        }
    }

    @ApiOperation(value = "下发指定播报信息", response = Result.class)
    @PostMapping("/getPublishJson")
    public Result getPublishJson(@RequestParam String serverUrl) {
        List<StreamInfo> streamInfos = streamInfoMapper.selectList(new QueryWrapper<StreamInfo>().eq("server_url", serverUrl));
        List<Map<String, Object>> jsons = new ArrayList<>();

        for (StreamInfo streamInfo : streamInfos) {
            int id = streamInfo.getId();
            List<Rule> areas = ruleMapper.selectList(new QueryWrapper<Rule>().eq("stream_info_id", id));
            StreamInfo info = streamInfoMapper.selectById(id);

            Map<String, Object> jsonMap = createVoiceJson(info, areas);
            jsonMap.replaceAll((key, value) -> {
                if (value == null) {
                    return "";
                } else if (value instanceof Collection && ((Collection<?>) value).isEmpty()) {
                    return new ArrayList<>();
                } else {
                    return value;
                }
            });

            jsons.add(jsonMap);
        }

        return Result.OK("批量下发json获取成功！", jsons);
    }


    @ApiOperation(value = "查询语音播报信息", response = Result.class)
    @GetMapping("/search")
    public Result search(@RequestParam(value = "curPage", defaultValue = "1") Integer curPage,
                         @RequestParam(value = "curSize", defaultValue = "10") Integer curSize,
                         @RequestParam(value = "keyword", required = false) String keyword) {

        // 创建 Page 对象，指定泛型参数为 StreamInfo
        Page<StreamInfo> page = new Page<>(curPage, curSize);

        QueryWrapper<StreamInfo> queryWrapper = new QueryWrapper<>();

        if (keyword != null && !keyword.trim().isEmpty()) {
            queryWrapper.lambda()
                    .like(StreamInfo::getName, keyword)
                    .or()
                    .like(StreamInfo::getAudioIp, keyword)
                    .or()
                    .like(StreamInfo::getUrl, keyword)
                    .or()
                    .like(StreamInfo::getId, keyword)
                    .or()
                    .like(StreamInfo::getServerUrl, keyword);
        }

        // 分页查询 StreamInfo 数据
        IPage<StreamInfo> streamInfoPage = streamInfoMapper.selectPage(page, queryWrapper);

        // 转换为 StreamInfoVo
        List<StreamInfoVo> streamInfoVoList = streamInfoPage.getRecords().stream().map(streamInfo -> {
                    StreamInfoVo streamInfoVo = new StreamInfoVo();
                    streamInfoVo.setId(streamInfo.getId());
                    streamInfoVo.setName(streamInfo.getName());
                    streamInfoVo.setAudioIp(streamInfo.getAudioIp());
                    streamInfoVo.setUrl(streamInfo.getUrl());

                    // 根据 StreamInfo 的 id 查询对应的 Rule 列表
                    List<Rule> ruleList = ruleMapper.selectList(new QueryWrapper<Rule>().lambda().eq(Rule::getStreamInfoId, streamInfo.getId()));
                    List<StreamInfoVo.Rule> ruleVoList = ruleList.stream().map(rule -> {
                        StreamInfoVo.Rule ruleVo = new StreamInfoVo.Rule();
                        // 使用 split 拆分 area 字符串
                        String areaString = rule.getArea();
                        List<String> areas = Arrays.stream(areaString.split("\\|"))
                                .collect(Collectors.toList());
                        ruleVo.setId(rule.getId());
                        ruleVo.setAreas(areas);
                        ruleVo.setType(rule.getType());
                        ruleVo.setAreaName(rule.getAreaName());
                        // 关联label-value
                        LabelValue labelValue = labelValueMapper.selectOne(new QueryWrapper<LabelValue>().eq("value", rule.getType()));
                        if (labelValue != null) {
                            ruleVo.setLabel(labelValue.getLabel());
                            ruleVo.setColor(labelValue.getColor());
                        }
                        return ruleVo;
                    }).collect(Collectors.toList());

                    // 设置规则列表
                    streamInfoVo.setRules(ruleVoList);

                    return streamInfoVo;
                }).sorted(Comparator.comparingInt(StreamInfoVo::getId).reversed())// 按照 ID 降序排序
                .collect(Collectors.toList());

        // 将转换后的结果设置到 Page 对象中
        Page<StreamInfoVo> resultPage = new Page<>(curPage, curSize);
        resultPage.setRecords(streamInfoVoList);
        resultPage.setTotal(streamInfoPage.getTotal());

        return Result.OK("查询成功", resultPage);
    }

    @ApiOperation(value = "根据ID查询某个视频流的所有规则", response = Result.class)
    @GetMapping("/getRulesByInfoId")
    public Result getRulesByInfoId(@RequestParam(value = "curPage", defaultValue = "1") Integer curPage,
                                   @RequestParam(value = "curSize", defaultValue = "10") Integer curSize,
                                   @RequestParam(value = "id") Integer id) {
        Page<StreamInfoVo.Rule> page = new Page<>(curPage, curSize);
        // 根据 StreamInfo 的 id 查询对应的 Rule 列表
        List<Rule> ruleList = ruleMapper.selectList(new QueryWrapper<Rule>().lambda().eq(Rule::getStreamInfoId, id));
        List<StreamInfoVo.Rule> ruleVoList = ruleList.stream().map(rule -> {
            StreamInfoVo.Rule ruleVo = new StreamInfoVo.Rule();
            String areaString = rule.getArea();
            List<String> areas = Arrays.stream(areaString.split("\\|"))
                    .collect(Collectors.toList());
            ruleVo.setAreas(areas);
            ruleVo.setType(rule.getType());
            ruleVo.setAreaName(rule.getAreaName());
            LabelValue labelValue = labelValueMapper.selectOne(new QueryWrapper<LabelValue>().eq("value", rule.getType()));
            ruleVo.setId(rule.getId());
            if (labelValue != null) {
                ruleVo.setLabel(labelValue.label);
                ruleVo.setColor(labelValue.getColor());
            }
            return ruleVo;
        }).sorted(Comparator.comparingInt(StreamInfoVo.Rule::getId).reversed()).collect(Collectors.toList());
        page.setRecords(ruleVoList);
        return Result.OK("查询成功", page);
    }

    private Map<String, Object> createVoiceJson(StreamInfo info, List<Rule> areas) {
        Map<String, Object> jsonMap = new HashMap<>();
        // 设置 Voice 的基础属性
        jsonMap.put("name", info.getName());
        jsonMap.put("stream_id", String.valueOf(info.getId()));
        jsonMap.put("audio_ip", info.getAudioIp());
        jsonMap.put("url", info.getUrl());
        // 处理 Rule 数据
        List<Map<String, Object>> rules = areas.stream().map(area -> {
            Map<String, Object> rule = new HashMap<>();
            List<String> areaList = Arrays.asList(area.getArea().split("\\|"));
            rule.put("areas", areaList);
            rule.put("type", area.getType());
            return rule;
        }).collect(Collectors.toList());

        jsonMap.put("rules", rules);

        return jsonMap;
    }
}
